package wangxiaotao.utils;


import cn.hutool.core.util.IdUtil;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import java.util.Date;

/**
 * JWT由3部分组成：标头(Header)、有效载荷(Payload)和签名(Signature)。
 */
@Slf4j
@Component//@value给静态变量赋值 需要加入此注解
@ConfigurationProperties(value = "jjwt.token")
public class JWTUtils {

    //密钥
    private static String secret;

    //超时时间 分钟
    private static Integer timeout;

    //set方法必须为public 不然无法写入进去
    public void setSecret(String secret) {
        JWTUtils.secret = secret;
    }

    public void setTimeout(Integer timeout) {
        JWTUtils.timeout = timeout;
    }


    public static String createToken(Integer uId){
        Assert.notNull(uId,"建立jwt传入的参数不能为空");
        Assert.notNull(secret,"建立jwt传入的secret不能为空");
        Assert.notNull(timeout,"建立jwt传入的timeout不能为空");
        Date nowDate = new Date();
        Date outDate = new Date(nowDate.getTime() + timeout * 60 * 1000);;
        log.info("---------> token创建成功，超时时间为：{}",outDate);
        //生成token
        String randomUUID = IdUtil.randomUUID();

        return Jwts.builder()
                //标头(Header)
                .setHeaderParam("typ", "JWT")
                //有效载荷(Payload)
                .setId(randomUUID)//唯一身份标识，主要用来作为一次性token,从而回避重放攻击。
                .setSubject("user")//所面向的用户
                .claim("id",uId)
                .setIssuedAt(nowDate)//签发时间
                .setExpiration(outDate)//过期时间
                .signWith(SignatureAlgorithm.HS512,secret)
                .compact();//设置加密算法和密钥
    }

    /**
     * 解析token 获取载荷
     * @param token
     * @return
     */
    public static Claims getClaimsByToken(String token){
        return Jwts.parser()//解析token
                .setSigningKey(secret)//设置密钥
                .parseClaimsJws(token)//要解析的token
                .getBody();//获取Claims
    }

    /**
     * 获取荷载里面的详细信息
     * @param token
     * @param name
     * @return
     */
    public static String getClaimByName(String token,String name){
        return Jwts.parser()//解析token
                .setSigningKey(secret)//设置密钥
                .parseClaimsJws(token)//要解析的token
                .getBody().get(name).toString();

    }

    /**
     * 获取过期剩余时间
     * @param token
     * @return 分钟
     */
    public static Long getExpiredTime(String token){
        Claims body = Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
        return (new Date().getTime() - body.getExpiration().getTime())/1000%60;
    }

    /**
     * 获取id
     * @param token
     * @return
     */
    public static String getId(String token){
        return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody().getId();
    }

    /**
     * token是否过期
     */
    public static void isTokenExpired(String token) throws JwtException {
        Jwts.parser().setSigningKey(secret).parse(token);
    }
}
